import NativeHelper from "../comm/NativeHelper";
import USDate from "../comm/USDate";
import { Toast } from "../components/Toast";
// import { CfgItemID } from "../configs/CfgItem";
import { EnvType, GameConfig, UIID } from "../data/GameConfig";
import LocalValues from "../data/LocalValues";
import { LocalKey } from "../data/LocalValues";
import UserModel from "../data/UserModel";
// import GameCtrl from "../game/GameCtrl";
import { EventMgr, EventName } from "../manager/EventMgr";
import { ABTest, ABTestKey } from "../net/ABTest";
import { AdPos, AdType, EventReport, ReportDataAdTypeChange } from "../net/EventReport";
import TDCtrl from "./TDCtrl";

const BANNER_UIIDS = [
    UIID.UIHall,
]
export default class ADCtrl {
    private static _instance: ADCtrl = null;
    public static get instance() {
        if (!this._instance) {
            this._instance = new ADCtrl();
        }
        return this._instance;
    }
    private _data: IADData = null;
    public lastClickAdPos: AdPos = null;
    private adCount = 0; // 插屏和激励广告 展示次数
    private bAdTypeChange = false;
    public init() {
        EventMgr.on(EventName.onTomorrow, this.onTomorrow, this);
        this._data = LocalValues.getObject(LocalKey.adData);
        if (!this._data) {
            this._data = {
                adRewardedCount: 0,
                usedPropCount: 0,
                usedItemIds: [],
                adWeight: 0,
                adGrade: 0,
                adInterval: 0,
                todayInterAdCount: 0,
                todayIdx: USDate.dayIdx(),
                noAdTimeTo: 0,
                regTime: Date.now(),
            };
        }
        if (this._data.todayIdx != USDate.dayIdx()) {
            this.onTomorrow();
        }
        // NativeHelper.callAdLoadInter();
        // NativeHelper.callAdLoadRewarded();
        EventMgr.on(EventName.onAdLoadInter, this.onAdLoadInter, this);
        EventMgr.on(EventName.onAdLoadRewarded, this.onAdLoadRewarded, this);
        EventMgr.on(EventName.onShowAdInter, this.onShowAdInter, this);
        EventMgr.on(EventName.onShowAdRewarded, this.onShowAdRewarded, this);
        EventMgr.on('onAdTypeChange', this.onAdTypeChange, this);
        EventMgr.on('onTopUIChange', this.onTopUIChange, this);
        this.loadInterstitial();
        this.loadRewarded();
        this.loadBanner();
    }
    public loadInterstitial() {
        NativeHelper.callAdLoad('interstitial');
        EventReport.ad_pull_start({
            adpos: AdPos.none,
            adtype: AdType.interstitial,
        });
    }
    public loadRewarded() {
        NativeHelper.callAdLoad('rewarded');
        EventReport.ad_pull_start({
            adpos: AdPos.none,
            adtype: AdType.rewarded,
        });
    }
    public loadBanner() {
        NativeHelper.callAdLoad('banner');
    }
    public addNoAdTime(time: number) {
        console.log('###ADCtrl addNoAdTime###', time);
        let timeTo = Math.max(this._data.noAdTimeTo, Date.now());
        this._data.noAdTimeTo = timeTo + time;
        this.save();
    }
    public get needChangeAdType() {
        const interval = 3;
        return (this.adCount + 1) % (interval + 1) == 0;
    }
    //====几个收集信息的回调====
    private onAdLoadInter(bSuccess: boolean, str: string) {
        console.log('###ADCtrl onAdLoadInter###', bSuccess, str);
        if (bSuccess) {
            EventReport.ad_pull_success({
                adpos: AdPos.none,
                adtype: AdType.interstitial,
            });
            if (!LocalValues.getBoolean(LocalKey.first_fill_ad_info_i)) {
                LocalValues.setBoolean(LocalKey.first_fill_ad_info_i, true);
                let obj = JSON.parse(str);
                EventReport.first_fill_ad_info_i({
                    level: UserModel.curLevelId,
                    ...obj
                });
            }
        } else {
            EventReport.ad_pull_failed({
                adfailedreason: str,
                adpos: AdPos.none,
                adtype: AdType.interstitial,
            });
        }
    }
    private onAdLoadRewarded(bSuccess: boolean, str: string) {
        console.log('###ADCtrl onAdLoadRewarded###', bSuccess, str);
        if (bSuccess) {
            EventReport.ad_pull_success({
                adpos: AdPos.none,
                adtype: AdType.rewarded,
            });
            if (!LocalValues.getBoolean(LocalKey.first_fill_ad_info_v)) {
                LocalValues.setBoolean(LocalKey.first_fill_ad_info_v, true);
                let obj = JSON.parse(str);
                EventReport.first_fill_ad_info_v({
                    level: UserModel.curLevelId,
                    ...obj
                });
            }
        } else {
            EventReport.ad_pull_failed({
                adfailedreason: str,
                adpos: AdPos.none,
                adtype: AdType.rewarded,
            });
        }
    }
    private onShowAdInter(bSuccess: boolean) {
        console.log('###ADCtrl onShowAdInter###', bSuccess);
        if (bSuccess) {
            // EventReport.ad_show({
            //     adpos: AdPos.end_level,
            //     level: GameCtrl.gamingLevel,
            // });
            TDCtrl.instance.onAdInsert();
            this.loadInterstitial();
            this.adCount ++;
        }
        this.bAdTypeChange = false;
        LocalValues.addCount('ad_count_total');
        this.onAdCountTotalChange();
    }
    private onShowAdRewarded(bSuccess: boolean) {
        console.log('###ADCtrl onShowAdRewarded###', bSuccess);
        if (bSuccess) {
            this.loadRewarded();
            if (!this.bAdTypeChange) {
                this.adCount ++;
            }
        } else {
            Toast.show('Play Ad Failed');
        }
        this.bAdTypeChange = false;
        LocalValues.addCount('ad_count_total');
        this.onAdCountTotalChange();
        // if (bSuccess && this.lastClickAdPos) {
        //     EventReport.ad_show({
        //         adpos: this.lastClickAdPos,
        //         level: GameCtrl.gamingLevel,
        //     });
        // }
    }
    private _adCountReportNums = [8, 10, 15, 20, 30, 50, 100];
    private onAdCountTotalChange() {
        const adCountTotal = LocalValues.getCount('ad_count_total');
        for (const num of this._adCountReportNums) {
            if (adCountTotal == num) {
                const event: any = 'ads' + num;
                EventReport.report(event);
            }
        }
    }
    private onAdTypeChange(json: string) {
        console.log('###ADCtrl onAdTypeChange', json);
        const data: ReportDataAdTypeChange = JSON.parse(json);
        EventReport.ad_type_change(data);
        this.bAdTypeChange = true;
        if (data.adTypeBefore == AdType.interstitial) {
            // 插屏转激励 重置adCount
            this.adCount = 0;
        } else {
            // 激励转插屏 插屏的监听需要处理成激励奖励
        }
    }
    private _timeoutBanner: any;
    private onTopUIChange(uiId: number) {
        console.log('###ADCtrl onTopUIChange###', uiId);
        if (ABTest.getKey(ABTestKey.bannerShowState) == 2) {
            clearTimeout(this._timeoutBanner);
            this._timeoutBanner = setTimeout(() => {
                if (BANNER_UIIDS.indexOf(uiId) != -1) {
                    NativeHelper.callAdBanner(true, {
                        placement: {
                            adPos: AdPos.none,
                        },
                        customData: {
                            // level: GameCtrl.gamingLevel,
                            level: 0,
                            version: GameConfig.version,
                            isTest: GameConfig.envType == EnvType.Test,
                            adPos: AdPos.none,
                        }
                    });
                } else {
                    NativeHelper.callAdBanner(false);
                }
            }, 50);
        }
    }
    /**玩家主动看完激励广告 */
    public onAdRewarded() {
        console.log('###ADCtrl onAdRewarded###');
        if (UserModel.curLevelId > this.startLevel) {
            if (this._data.adGrade == 3) {
                this._data.adInterval = 0;
                this.save();
            }
        } else {
            this._data.adRewardedCount++;
            this.save();
        }
        EventReport.ad_view_rewards_collect({
            adpos: this.lastClickAdPos,
            adtime: Date.now(),
            adtype: AdType.rewarded,
            rewardsdeliverstatus: 'Yes',
        });
        TDCtrl.instance.onAdRewarded();
    }
    // /**玩家主动使用道具 */
    // public onUsedProp(itemId: CfgItemID) {
    //     console.log('###ADCtrl onUsedProp###', itemId);
    //     if (UserModel.curLevelId > this.startLevel) {
    //         return;
    //     }
    //     this._data.usedPropCount++;
    //     if (this._data.usedItemIds.indexOf(itemId) == -1) {
    //         this._data.usedItemIds.push(itemId);
    //     }
    //     this.save();
    // }
    private get startLevel() {
        // const bTomorrow = Date.now() - this._data.regTime > 24 * 60 * 60 * 1000;
        // return bTomorrow ? 4 : 10;
        return 15;
    }
    public onGameEnd() {
        if (UserModel.curLevelId <= this.startLevel) {
            return;
        }
        if (!this._data.adGrade) {
            // 计算adWeight
            // adWeight = (1+adRewardedCount/2)*(20+usedPropCount)/(35+usedKindCount)
            // n = (1+k/2)*(20+m)/(35+M)
            // n = (1+k*0.6+k*k*0.1)*(5+0.2*m+0.5*M)/10
            const k = this._data.adRewardedCount;
            const m = this._data.usedPropCount;
            const M = this._data.usedItemIds.length;
            const n = (1 + k / 2) * (20 + m) / (35 + M);
            // const n = (1 + k * 0.6 + k * k * 0.1) * (5 + 0.2 * m + 0.5 * M) / 10;
            this._data.adWeight = n;
            console.log('计算adWeight', 'k', k, 'm', m, 'M', M, '=n', n);
            if (n < 1) {
                this._data.adGrade = 1;
                this._data.adInterval = 2;
            } else if (n < 2) {
                this._data.adGrade = 2;
                this._data.adInterval = 3;
            } else {
                this._data.adGrade = 3;
                this._data.adInterval = 0;
            }
            this.save();
        }
        // if (UserModel.curLevelId == this.startLevel + 1) {
        //     return;
        // }
        let interval = this._data.adInterval;
        let todayInterAdCount = this._data.todayInterAdCount;
        const grade = this._data.adGrade;
        let bPlayAd = false;
        if (grade == 1) {
            if (interval >= 2) {
                bPlayAd = true;
            } else if (todayInterAdCount >= 5) {
                bPlayAd = true;
            }
        } else if (grade == 2) {
            if (interval >= 3) {
                bPlayAd = true;
            } else if (todayInterAdCount >= 5) {
                bPlayAd = true;
            }
        } else {
            if (interval >= 5) {
                bPlayAd = true;
            }
        }
        const bNoAd = this._data.noAdTimeTo > Date.now();
        console.log('###ADCtrl onGameEnd###', 'bPlayAd', bPlayAd, 'bNoAd', bNoAd);
        if (bPlayAd && !bNoAd) {
            this._data.todayInterAdCount++;
            this._data.adInterval = 0;
        } else {
            this._data.adInterval++;
        }
        this.save();
        if (bPlayAd && !bNoAd) {
            NativeHelper.callShowAdInter({
                placement: {
                    adPos: AdPos.none,
                },
                customData: {
                    // level: GameCtrl.gamingLevel,
                    level: 0,
                    version: GameConfig.version,
                    isTest: GameConfig.envType == EnvType.Test,
                    adPos: AdPos.none,
                },
                changeAdType: this.needChangeAdType
            });
            // EventReport.ad_show({
            //     adpos: AdPos.end_level,
            //     level: GameCtrl.gamingLevel,
            // });
        }
    }
    //===========end===========

    private onTomorrow() {
        console.log('###ADCtrl onTomorrow###');
        this._data.todayIdx = USDate.dayIdx();
        this._data.todayInterAdCount = 0;
        this.save();
    }

    private save() {
        LocalValues.setObject(LocalKey.adData, this._data);
    }
}
export interface IADData {
    // 前15关收集信息
    adRewardedCount: number; // btnAd点击并播放完成次数
    usedPropCount: number; // 非教学免费使用的道具总次数（包含prop和booster）
    usedItemIds: number[]; // 使用过的道具id
    // 15关时确定adWeight、adGrade
    adWeight: number; // ad权重
    adGrade: number; // ad等级
    //======分割线======
    adInterval: number; // 当前广告播放间隔：adGrade1 初始2，adGrade2 初始3，adGrade3 初始0
    todayInterAdCount: number; // 今天播放的插屏广告数量
    todayIdx: number; // 今天日期idx
    noAdTimeTo: number; // 禁止播放广告的时间戳
    regTime: number;
}
